#include "ObjReader.hpp"
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <GL/glfw.h>

using std::vector;
/** Read object file. Taken from "wikibooks" opengl */
bool ObjReader::ReadFile(const char* filename, VertexList& VList, TriangleList& TList)
{

	std::ifstream in(filename, std::ios::in);
	if (!in)
	{
		std::cout << "Cannot open " << filename << std::endl;
		return false;
	}
	vector<float> Vertices, Normals;
	vector<float> TriangleNormals;
	vector<GLuint> Triangles;
	std::string line;
	while (getline(in, line))
	{
		if (line.substr(0,2) == "v ")
		{
			std::istringstream s(line.substr(2));
			float x,y,z;
			s >> x; s >> y; s >> z;
			Vertices.push_back(x);
			Vertices.push_back(y);
			Vertices.push_back(z);
		}
		else if (line.substr(0,2) == "f ")
		{
			std::istringstream s(line.substr(2));
			GLuint a,b,c;
			s >> a; s >> b; s >> c;
			a--; b--; c--;
			Triangles.push_back(a);
			Triangles.push_back(b);
			Triangles.push_back(c);
		}
		else if (line[0] == '#') { /* ignoring this line */ }
		else { /* ignoring this line */ }
	}

	Normals.resize(Vertices.size(), 0.0f);
	TriangleNormals.resize(Triangles.size(), 0.0f);
	for (unsigned int i = 0; i < Triangles.size(); i+=3)
	{
		GLuint ia = Triangles[i];
		GLuint ib = Triangles[i+1];
		GLuint ic = Triangles[i+2];
		Vector3 V1 = Vector3(Vertices[ia * 3 + 0], Vertices[ia * 3 + 1], Vertices[ia * 3 + 2]);
		Vector3 V2 = Vector3(Vertices[ib * 3 + 0], Vertices[ib * 3 + 1], Vertices[ib * 3 + 2]);
		Vector3 V3 = Vector3(Vertices[ic * 3 + 0], Vertices[ic * 3 + 1], Vertices[ic * 3 + 2]);
		Vector3 Normal = (V2 - V1).Cross(V3 - V1).Norm();

		//normals[ia] = normals[ib] = normals[ic] = normal;
		TriangleNormals[i] = Normal.x;
		TriangleNormals[i + 1] = Normal.y;
		TriangleNormals[i + 2] = Normal.z;

		Normals[ia * 3 + 0] += Normal.x;
		Normals[ia * 3 + 1] += Normal.y;
		Normals[ia * 3 + 2] += Normal.z;

		Normals[ib * 3 + 0] += Normal.x;
		Normals[ib * 3 + 1] += Normal.y;
		Normals[ib * 3 + 2] += Normal.z;

		Normals[ic * 3 + 0] += Normal.x;
		Normals[ic * 3 + 1] += Normal.y;
		Normals[ic * 3 + 2] += Normal.z;

	}
	for(unsigned int i = 0; i < Normals.size(); i += 3)
	{
		Vector3 Normal = Vector3(Normals[i], Normals[i + 1], Normals[i + 2]);
		Normal = Normal.Norm();
		Normals[i] = Normal.x; Normals[i + 1] = Normal.y; Normals[i + 2] = Normal.z;
	}

	float* VertexArray = new float[Vertices.size()];
	float* NormalsArray = new float[Normals.size()];
	GLuint* TrianglesArray = new GLuint[Triangles.size()];

	for(unsigned int i = 0; i < Vertices.size(); i ++)
	{
		VertexArray[i] = Vertices[i];
		NormalsArray[i] = Normals[i];
	}
	for(unsigned int i = 0; i < Triangles.size(); i ++)
	{
		TrianglesArray[i] = Triangles[i];
	}

	VList = VertexList(VertexArray, NormalsArray, Vertices.size());
	TList = TriangleList(TrianglesArray, Triangles.size());

	return true;
}
